package com.yuanjing.xiangqinxiangai.plugin

import android.os.Build
import androidx.annotation.RequiresApi
import com.google.gson.Gson
import com.yuanjing.xiangqinxiangai.model.AppConfig
import com.yuanjing.xiangqinxiangai.model.RoomDataModel
import com.yuanjing.xiangqinxiangai.model.RoomInfo
import com.yuanjing.xiangqinxiangai.util.LiveEngineUtil
import com.yuanjing.xiangqinxiangai.view.LivePreviewView
import im.zego.zegoexpress.ZegoExpressEngine
import im.zego.zegoexpress.constants.ZegoRoomStreamListType
import im.zego.zegoexpress.entity.ZegoRoomConfig
import im.zego.zegoexpress.entity.ZegoUser
import io.flutter.embedding.engine.dart.DartExecutor
import io.flutter.plugin.common.BasicMessageChannel
import io.flutter.plugin.common.StandardMessageCodec
import org.json.JSONObject

class LiveMessagePlugin(private val messenger: DartExecutor) {

    val messageChannel: BasicMessageChannel<Any>
    var appConfig: AppConfig? = null
    var roomInfo: RoomInfo? = null
    var roomData: RoomDataModel? = null

    // 用于存储直播预览视图
    val livePreviewMap: MutableMap<Int, LivePreviewView?> = mutableMapOf()

    init {
        // 获取 FlutterEngine 的 BinaryMessenger
//        val messenger = activity.flutterEngine?.dartExecutor

        // 设置 BasicMessageChannel 频道名称与 Flutter 端保持一致
        messageChannel =
            BasicMessageChannel(messenger, "LiveMessagePlugin", StandardMessageCodec.INSTANCE)

        // 设置消息处理器
        messageChannel.setMessageHandler { message, reply ->
            if (message is HashMap<*, *>) {
                try {
                    val method = message.get("method")
                    val action = message.get("action")
                    val viewId = message.get("viewId")
                    val data = message.get("data").toString()

                    when (method) {
                        "zegoInit" -> zegoInit(data, reply)
                        "loginRoom" -> loginRoom(data, reply)
                        "logoutRoom" -> logoutRoom(data, reply)
                        "refreshMaiInfo" -> refreshMaiInfo(data, reply)
                        else -> reply.reply("Invalid method")
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                    reply.reply("Error parsing message")
                }
            } else {
                reply.reply("Invalid message format")
            }
        }
    }

    // zegoInit 方法：初始化 Zego 引擎
    private fun zegoInit(data: String, reply: BasicMessageChannel.Reply<Any>) {
        try {
            appConfig = Gson().fromJson(data, AppConfig::class.java)
            LiveEngineUtil.init(appConfig!!)
            reply.reply(result(0, 0, "success"))
        } catch (e: Exception) {
            e.printStackTrace()
            reply.reply(result(-1, 0, "appconfig 参数未传"))
        }
    }

    // loginRoom 方法：登录房间
    private fun loginRoom(data: String, reply: BasicMessageChannel.Reply<Any>) {
        try {
            val roomInfoJson = JSONObject(data)
            roomInfo = Gson().fromJson(data, RoomInfo::class.java)

            // 登录房间的逻辑
            LiveEngineUtil.engine
                .loginRoom(roomInfo?.id.toString(), ZegoUser(roomInfo?.selfUserId.toString()))

            reply.reply(result(0, 0, "success"))
        } catch (e: Exception) {
            e.printStackTrace()
            reply.reply(result(-1, 0, "RoomInfo 参数未传"))
        }
    }

    // logoutRoom 方法：退出房间
    private fun logoutRoom(data: String, reply: BasicMessageChannel.Reply<Any>) {
        // 退出房间的逻辑
        // LiveEngineUtil.engine.logoutRoom()
        val user = ZegoUser(roomInfo?.selfUserId.toString())
        val roomConfig = ZegoRoomConfig()
        roomConfig.isUserStatusNotify = true
        LiveEngineUtil.engine.loginRoom(
            roomInfo?.id.toString(),
            user,
            roomConfig
        ) { error, extendedData ->
            if (error == 0 || error == 1002001) {
                reply.reply(result(0, 0, "success"))
            } else {
//                UserBehaviorUtil.postToService("zego.login.fail", error)
//                ZZToast.showError("加入房间失败（$error）")
//                LogUtils.e("error: $error extendedData: $extendedData")
            }
        }
    }

    // refreshMaiInfo 方法：刷新麦位信息
    private fun refreshMaiInfo(data: String, reply: BasicMessageChannel.Reply<Any>) {
        try {
            roomData = Gson().fromJson(data, RoomDataModel::class.java)

            //只处理 状态0 ，2
            var selfMaiEntity: RoomDataModel.RoomMai? = null
            val streamList = mutableListOf<String>()
            livePreviewMap.forEach { item ->
                item.value?.let { liveRenderLayout ->
                    if (!liveRenderLayout.streamID.isNullOrEmpty()) {
                        streamList.add(liveRenderLayout.streamID ?: "")
                        liveRenderLayout.startPreview()
                    }
                    if (liveRenderLayout.roomMais.isAnchor()) selfMaiEntity =
                        liveRenderLayout.roomMais
                }

            }
            if (selfMaiEntity == null) {
                LiveEngineUtil.engine.stopPreview()
                LiveEngineUtil.engine.stopPublishingStream()
                LiveEngineUtil.engine.mutePublishStreamVideo(true)
            } else if (selfMaiEntity?.status == 2) {
                LiveEngineUtil.engine.mutePublishStreamVideo(true)
            }
            val playStream =
                LiveEngineUtil.engine.getRoomStreamList(
                    roomInfo?.id.toString(),
                    ZegoRoomStreamListType.PLAY
                )
            if (playStream?.playStreamList != null) for (item in playStream.playStreamList!!) {
                if (!streamList.contains(item.streamID)) {//|| !AppUtils.isAppForeground() || isDeviceLocked()
                    LiveEngineUtil.engine.stopPlayingStream(item.streamID ?: "")
                }
            }

            reply.reply(result(0, 0, "success"))
        } catch (e: Exception) {
            e.printStackTrace()
            reply.reply(result(-1, 0, "RoomData 参数未传"))
        }
    }

    // 用于返回操作结果的函数
    private fun result(code: Int, errorCode: Int, msg: String?): String {
        val result = JSONObject()
        try {
            result.put("code", code)
            result.put("errorCode", errorCode)
            result.put("msg", msg)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return result.toString()
    }


}
